﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;

namespace PHMEE.Admin
{
    /// <summary>
    /// 主动触发数采器的操作命令
    /// </summary>
    public class DtSendTopicService : PHMEEAdminAppService, IDtSendTopicService
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<DtSendTopicService> _logger;
        private readonly ISysParaRepository _sysRepository;
        private readonly RedisHelper _redisHelper;
        private readonly IMqttExtendAppService _mqttExtend;
        private string PublishTopic;

        public DtSendTopicService(IConfiguration configuration, ILogger<DtSendTopicService> logger, ISysParaRepository sysRepository, RedisHelper redisHelper, IMqttExtendAppService mqttExtend)
        {
            _configuration = configuration;
            _logger = logger;
            _sysRepository = sysRepository;
            _mqttExtend = mqttExtend;
            _redisHelper = redisHelper;
            PublishTopic = $"{_configuration.GetValue<string>("MqttClient:Prefix")}";
        }
        /// <summary>
        /// 发送启动数采器命令
        /// </summary>
        public async Task<bool> SendIssueRestartAsync(string collectorCode)
        {
            string sendTopic = $"{PublishTopic}/{collectorCode}/IssueRestart/0";
            string msg = "1"; // 负载: 1-软重启

            return await _mqttExtend.SendMessageAsync(sendTopic, msg);
        }
        /// <summary>
        /// 发送自诊断命令并且返回未在线的编号
        /// </summary>
        public async Task<List<string>> CheckDataAsync(List<string> collectorCodes)
        {
            var failedCollectors = new List<string>();

            foreach (var collectorCode in collectorCodes)
            {
                var stopwatch = Stopwatch.StartNew();

                string sendTopic = $"{PublishTopic}/{collectorCode}/IssueCheckData/0";
                string msg = "1"; // 负载: 自诊断请求

                // 发送MQTT自诊断请求
                await _mqttExtend.SendMessageAsync(sendTopic, msg);

                // 设置轮询间隔和超时时间
                int maxWaitTime = 20000; // 设置最大等待时间为 20 秒
                int interval = 500; // 每隔500毫秒检查一次
                int elapsedTime = 0;

                // 轮询Redis，直到数据存在或超时
                bool isSuccess = false;
                while (elapsedTime < maxWaitTime)
                {
                    // 检查 Redis 中是否存在自诊断数据
                    bool isDataAvailable = await _redisHelper.KeyExistsAsync($"PhmeeAdmin_Mqtt_CheckData_{collectorCode}");

                    if (isDataAvailable)
                    {
                        // 如果数据存在，获取并反序列化
                        var jsonData = await _redisHelper.GetStringAsync($"PhmeeAdmin_Mqtt_CheckData_{collectorCode}");

                        if (!string.IsNullOrEmpty(jsonData))
                        {
                            stopwatch.Stop();
                            Console.WriteLine($"CheckDataAsync for {collectorCode} 执行时间: {stopwatch.ElapsedMilliseconds} 毫秒");

                            isSuccess = true;
                            break;
                        }
                    }

                    // 如果数据还没有准备好，等待一段时间后再试
                    await Task.Delay(interval);
                    elapsedTime += interval;
                }

                // 如果超时，记录到失败集合
                if (!isSuccess)
                {
                    failedCollectors.Add(collectorCode);
                }

                // 停止计时
                stopwatch.Stop();
            }

            return failedCollectors; // 返回失败的采集器集合
        }
        /// <summary>
        /// 下发参数命令
        /// </summary>
        public async Task<bool> SendIssueParaAsync(string collectorCode)
        {
            string sendTopic = $"{PublishTopic}/{collectorCode}/IssuePara/0";
            var sysPara = await _sysRepository.FirstOrDefaultAsync(p => p.CollectorCode == collectorCode);

            if (sysPara == null)
            {
                throw new UserFriendlyException("数采器不存在", "指定的数采器编号无效").WithData("collectorCode", collectorCode);
            }

            if (!sysPara.IsOnline)
            {
                throw new UserFriendlyException("未在线，无法下发！").WithData("collectorCode", collectorCode);
            }

            sysPara.ParaTime = DateTime.UtcNow;
            await _sysRepository.UpdateAsync(sysPara);

            string msg = JsonSerializer.Serialize(sysPara);
            return await _mqttExtend.SendMessageAsync(sendTopic, msg);
        }
    }
}
